﻿namespace EasyGo.Authentication
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Principal;
    using System.Web;
    using System.Web.Security;
    using EasyGo.Common.Auth;
    using EasyGo.Data;
    using Newtonsoft.Json;

    public class AuthenticationService : IAuthenticationService
    {
        private readonly ApplicationDbContext context;

        public AuthenticationService(ApplicationDbContext context)
        {
            this.context = context;
        }

        public bool TrySignIn(string email, string password, bool persistCookie)
        {
            var user = this.context.Users.SingleOrDefault(x => x.Email == email.ToLower());
            if (user != null)
            {
                if (user.Password == password)
                {
                    this.SetAuthCookie(
                        user.Email,
                        persistCookie,
                        new UserInfo
                            {
                                Email = user.Email,
                                Id = user.Id,
                                Name = user.FirstName + " " + user.LastName,
                                Role = user.Role
                            });
                    return true;
                }
            }

            return false;
        }

        public void SignOut()
        {
            FormsAuthentication.SignOut();
        }

        public void SetupPrincipal()
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (cookie != null)
            {
                var ticket = FormsAuthentication.Decrypt(cookie.Value);
                if (ticket != null)
                {
                    var info = JsonConvert.DeserializeObject<UserInfo>(ticket.UserData);

                    HttpContext.Current.User = new EasyGoPrincipal(
                        info.Email, info.Name, info.Id, UserRole.Admin, new GenericIdentity(info.Email));
                }
            }
        }

        private void SetAuthCookie(string email, bool rememberMe, UserInfo userData)
        {
            var cookie = FormsAuthentication.GetAuthCookie(email, rememberMe);
            var ticket = FormsAuthentication.Decrypt(cookie.Value);

            if (ticket == null)
            {
                return;
            }

            var newTicket = new FormsAuthenticationTicket(
                ticket.Version,
                ticket.Name,
                ticket.IssueDate,
                ticket.Expiration,
                ticket.IsPersistent,
                JsonConvert.SerializeObject(userData),
                ticket.CookiePath);

            var encTicket = FormsAuthentication.Encrypt(newTicket);

            cookie.Value = encTicket;

            HttpContext.Current.Response.Cookies.Add(cookie);
        }
    }
}